package efsGui;

import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JMenuBar;
import javax.swing.JMenu;
import javax.swing.JTree;
import java.awt.BorderLayout;
import java.awt.Rectangle;

import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.DefaultListModel;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JList;
import javax.swing.JPopupMenu;
import javax.swing.SwingUtilities;
import javax.swing.JOptionPane;
import javax.swing.SpringLayout;
import javax.swing.JScrollPane;
import javax.swing.UIManager;

import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;


import org.ejs.bean.FileManagerRemote;
import org.ejs.network.ServerAddress;

import client.ClientBeanThread;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;


public class EjsGui{
	
	public ServerAddress s;
	public static ClientBeanThread client;
	public FileManagerRemote file;
	boolean clientBeanThreadIsCreate = false;
	public static String pathHome;
	JFrame frame;
	static JTree tree = new JTree();
	String ip = "";
	int port = 0;

	/**
	 * Launch the application.
	 */
	public static String getHome(){
		return pathHome;
	}

	public static void main(String args[]) throws Exception { 
		
		try {
			UIManager.setLookAndFeel("com.jtattoo.plaf.texture.TextureLookAndFeel");
		} catch (Exception e) {
		    // If Nimbus is not available, you can set the GUI to another look and feel.
		}
		
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					EjsGui window = new EjsGui();
					window.frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the application.
	 */
	public EjsGui() {
		initialize();
	}

	/**
	 * Initialize the contents of the frame.
	 */
	@SuppressWarnings("rawtypes")
	private void initialize() {
		frame = new JFrame();
		frame.setResizable(false);
		frame.setBounds(100, 100, 700, 500);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		JMenuBar menuBar = new JMenuBar();
		frame.getContentPane().add(menuBar, BorderLayout.NORTH);
		
		JMenu mnMenu = new JMenu("Menu");
		menuBar.add(mnMenu);
		final JMenuItem mntmConnection = new JMenuItem("Connection");
		final JMenuItem mntmDeconnection = new JMenuItem("Deconnection");
		
		mntmConnection.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
		        String ipPort = JOptionPane.showInputDialog(null, "Parametre serveur : (ex: 192.168.1.254:1234", "Connection", 1);
		        
		        if(ipPort != null && ipPort.trim() != ""){
			        String pattern = "\\d{1,3}(?:\\.\\d{1,3}){3}(?::\\d{1,5})?";
			        
			        Pattern compiledPattern = Pattern.compile(pattern);
			        Matcher matcher = compiledPattern.matcher(ipPort);
			        if (matcher.find()) {
			        	String parameter[]=ipPort.split(":");
				        connection(parameter[0], Integer.parseInt(parameter[1]));
				        mntmConnection.setEnabled(false);
				        mntmDeconnection.setEnabled(true);
				  	}
		        }
			}
		});

		mntmDeconnection.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				deconnection();
				mntmConnection.setEnabled(true);
		        mntmDeconnection.setEnabled(false);
			}
		});
		
		mnMenu.add(mntmConnection);
		
		mntmDeconnection.setEnabled(false);
		mnMenu.add(mntmDeconnection);
		final JPanel panel = new JPanel();

		frame.getContentPane().add(panel, BorderLayout.CENTER);
		SpringLayout sl_panel = new SpringLayout();
		panel.setLayout(sl_panel);
		
		final JPanel panel_1 = new JPanel();
		sl_panel.putConstraint(SpringLayout.NORTH, panel_1, 41, SpringLayout.NORTH, panel);
		sl_panel.putConstraint(SpringLayout.WEST, panel_1, 10, SpringLayout.WEST, panel);
		sl_panel.putConstraint(SpringLayout.EAST, panel_1, 274, SpringLayout.WEST, panel);
		panel.add(panel_1);
		
		JPanel panel_2 = new JPanel();
		sl_panel.putConstraint(SpringLayout.NORTH, panel_2, 41, SpringLayout.NORTH, panel);
		sl_panel.putConstraint(SpringLayout.SOUTH, panel_2, -125, SpringLayout.SOUTH, panel);
		sl_panel.putConstraint(SpringLayout.SOUTH, panel_1, 0, SpringLayout.SOUTH, panel_2);
		sl_panel.putConstraint(SpringLayout.WEST, panel_2, 383, SpringLayout.WEST, panel);
		sl_panel.putConstraint(SpringLayout.EAST, panel_2, -10, SpringLayout.EAST, panel);
		panel.add(panel_2);
		final JList jlist = new JList();
		JScrollPane scrollPaneList = new JScrollPane(jlist);

		JButton btnNewButton = new JButton("Download");
		btnNewButton.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				// Get the index of all the selected items
			    int[] selectedIx = jlist.getSelectedIndices();
			    // Get all the selected items using the indices
			    for (int i = 0; i < selectedIx.length; i++) {
			      Object sel = jlist.getModel().getElementAt(selectedIx[i]);
			      download(sel.toString());
				    //Actualisation du JTree
	       			setClientBeanThread(pathHome);
	       			DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root");
	       			updateTree(new File(pathHome), root, tree);
	       			panel_1.updateUI();
			    }

			}
		});
		sl_panel.putConstraint(SpringLayout.NORTH, btnNewButton, 168, SpringLayout.NORTH, panel);
		sl_panel.putConstraint(SpringLayout.WEST, btnNewButton, 16, SpringLayout.EAST, panel_1);
		panel.add(btnNewButton);
		
		
//		Initialisation avec le refresh
//		jlist.setModel(new AbstractListModel() {
//			String[] values = new String[] {};
//			public int getSize() {
//				return values.length;
//			}
//			public Object getElementAt(int index) {
//				return values[index];
//			}
//		});
		
		
		JButton btnNewButton_1 = new JButton("Rafraichir");
		btnNewButton_1.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				getListFile(jlist);
			}
		});
		sl_panel.putConstraint(SpringLayout.SOUTH, btnNewButton_1, -6, SpringLayout.NORTH, panel_2);
		sl_panel.putConstraint(SpringLayout.EAST, btnNewButton_1, 0, SpringLayout.EAST, panel_2);
		panel.add(btnNewButton_1);
		
		JLabel lblLocal = new JLabel("Local");
		sl_panel.putConstraint(SpringLayout.WEST, lblLocal, 0, SpringLayout.WEST, panel_1);
		sl_panel.putConstraint(SpringLayout.SOUTH, lblLocal, -6, SpringLayout.NORTH, panel_1);
		panel_1.setLayout(new BorderLayout(0, 0));
		
		final JScrollPane scrollPane = new JScrollPane();
		panel_1.add(scrollPane, BorderLayout.CENTER);

		tree.addMouseListener(new MouseAdapter() {
	      public void mouseClicked(MouseEvent me) {
	    		  doMouseClicked(me, tree);
          }
		 });
		
		panel.add(lblLocal);
		
		JLabel lblDistant = new JLabel("Distant");
		sl_panel.putConstraint(SpringLayout.NORTH, lblDistant, 0, SpringLayout.NORTH, lblLocal);
		sl_panel.putConstraint(SpringLayout.WEST, lblDistant, 0, SpringLayout.WEST, panel_2);
		panel_2.setLayout(new BorderLayout(0, 0));
		

		panel_2.add(scrollPaneList, BorderLayout.CENTER);

		panel.add(lblDistant);
		
		JLabel label = new JLabel("<-------");
		sl_panel.putConstraint(SpringLayout.NORTH, label, 6, SpringLayout.SOUTH, btnNewButton);
		sl_panel.putConstraint(SpringLayout.WEST, label, 10, SpringLayout.WEST, btnNewButton);
		panel.add(label);
		
		JButton btnNewButton_2 = new JButton("Parcourir");
		btnNewButton_2.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				JFileChooser chooser = new JFileChooser();
		        chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
		        int returnVal = chooser.showOpenDialog(panel);
		        if(returnVal == JFileChooser.APPROVE_OPTION) {
		           System.out.println("You chose to open this file: " + chooser.getSelectedFile().getAbsolutePath());		           
		           		//String root = chooser.getSelectedFile().getAbsolutePath();
		           		pathHome = chooser.getSelectedFile().getAbsolutePath();
		           		setClientBeanThread(pathHome);
		           		DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root");
		           		remplirTree(chooser.getSelectedFile(), root, tree);
		        		scrollPane.setViewportView(tree);
		        		panel_1.updateUI();
	

		        }
			}
		});
		sl_panel.putConstraint(SpringLayout.NORTH, btnNewButton_2, 15, SpringLayout.SOUTH, panel_1);
		sl_panel.putConstraint(SpringLayout.WEST, btnNewButton_2, 0, SpringLayout.WEST, panel_1);
		sl_panel.putConstraint(SpringLayout.EAST, btnNewButton_2, 0, SpringLayout.EAST, panel_1);
		panel.add(btnNewButton_2);
		
		JButton btnNewButton_3 = new JButton("Move");
		sl_panel.putConstraint(SpringLayout.EAST, btnNewButton_3, 95, SpringLayout.EAST, panel_1);
		btnNewButton_3.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				// Get the index of all the selected items
			    int[] selectedIx = jlist.getSelectedIndices();
			    // Get all the selected items using the indices
			    for (int i = 0; i < selectedIx.length; i++) {
			      Object sel = jlist.getModel().getElementAt(selectedIx[i]);
			      getConnectionBeanThread().findAndMove(sel.toString());

			    }
			}
		});
		sl_panel.putConstraint(SpringLayout.NORTH, btnNewButton_3, 6, SpringLayout.SOUTH, label);
		sl_panel.putConstraint(SpringLayout.WEST, btnNewButton_3, 0, SpringLayout.WEST, btnNewButton);
		panel.add(btnNewButton_3);
	}
	
	
	
	
	
	
	
	

	public void connection(String ip, int port){
	   	 //TODO Appeller connection ici avec ip + port
		//s = new ServerAddress(ip, port);
		this.ip = ip;
		this.port = port;
		System.out.println("Ip saisie : " + ip + " Port Saisie : " + port);
	}
	
	public void deconnection(){
	   	 //TODO Appeller deconnection ici
		getConnectionBeanThread().getFile().disconnect();
		System.out.println("Deconnection");
	}
	
	public void getListFile(JList<String> jlist){
	   	 //TODO Appeller getListFile ici avec en remplacent arrList par l'appel Ejb

		List<String> arrList = getConnectionBeanThread().getAllFile(); 
		
		DefaultListModel<String> model = new DefaultListModel<String>();
		
		for (String file : arrList) {
			model.addElement(file);
		}
		jlist.setModel(model);
		jlist.updateUI();
	}

	public void download(String string) {
   	 //TODO Appeller download ici avec "string" en parametre
		getConnectionBeanThread().findAndDl(string);
		System.out.println("Fichier demandé :" + string + " Enregistré dans : " + EjsGui.getHome());
		
	}

	public void move(String string) {
    	 //TODO Appeller move ici avec "string" en parametre
		getConnectionBeanThread().findAndMove(string);
		System.out.println("Fichier demandé :" + string + " Deplacé dans : " + EjsGui.getHome());
	}
	
	public void remplirTree(File dossier, DefaultMutableTreeNode racine, JTree tree  ) {
		
	 	for(File file : dossier.listFiles()) {
	 	  
		 	 String fileName = file.getName();
		 	 if(file.isFile()){
		 		getConnectionBeanThread().getFile().add(file.getName());
		 	 }
		 	 DefaultMutableTreeNode noeudTree = new DefaultMutableTreeNode(fileName);
		 	  
		 	 try {
			 	 for(File fichier : file.listFiles()){
			 	   	 //TODO Appeller add ici me demander comment faire
			 	 DefaultMutableTreeNode node = new DefaultMutableTreeNode(fichier.getName());
			 	 noeudTree.add(listFile(fichier, node));
			  
			 	 }
		 	 } catch (NullPointerException e) {}
		 	  
		 	 racine.add(noeudTree);
	 	}
	 	 
	 	tree.setModel(new DefaultTreeModel(racine));
	 	tree.updateUI();
	 }
	  
	public void updateTree(File dossier, DefaultMutableTreeNode racine, JTree tree  ) {
		
	 	for(File file : dossier.listFiles()) {
	 	  
		 	 String fileName = file.getName();
		 	 DefaultMutableTreeNode noeudTree = new DefaultMutableTreeNode(fileName);
		 	  
		 	 try {
			 	 for(File fichier : file.listFiles()){
			 	   	 //TODO Appeller add ici me demander comment faire
			 	 DefaultMutableTreeNode node = new DefaultMutableTreeNode(fichier.getName());
			 	 noeudTree.add(listFile(fichier, node));
			  
			 	 }
		 	 } catch (NullPointerException e) {
		 		 
		 	 }
		 	  
		 	 racine.add(noeudTree);
	 	}
	 	 
	 	tree.setModel(new DefaultTreeModel(racine));
	 	tree.updateUI();
	 }
	
	 public static DefaultMutableTreeNode listFile(File file, DefaultMutableTreeNode node) {
	 	 
	 	if(file.isFile())
	 	 return new DefaultMutableTreeNode(file.getName());
	 	else {
	 	  
	 	 for (File nom : file.listFiles()) {
	 	 DefaultMutableTreeNode subNode;
	 	 if (nom.isDirectory()) {
	 	 subNode = new DefaultMutableTreeNode(nom.getName() + "\\");
	 	 node.add(listFile(nom, subNode));
	 	 } else {
	 	 subNode = new DefaultMutableTreeNode(nom.getName());
	 	 }
	  
	 	 node.add(subNode);
	 	 }
	 	  
	 	 return node;
	 	}
	 }
	 
	 public static void doMouseClicked(MouseEvent me, final JTree tree) {
		 if ( SwingUtilities.isRightMouseButton ( me ) )
         {
			 int row = tree.getClosestRowForLocation(me.getX(), me.getY());  
			 tree.setSelectionRow(row);  
			 final TreePath path = tree.getPathForLocation ( me.getX (), me.getY () );
             Rectangle pathBounds = tree.getUI ().getPathBounds ( tree, path );
             if ( pathBounds != null && pathBounds.contains ( me.getX (), me.getY () ) )
             {
                 JPopupMenu menu = new JPopupMenu ();
                 JMenuItem delete = new JMenuItem ( "Delete" );
                 menu.add (delete);
                 delete.addActionListener(new ActionListener() {
         			public void actionPerformed(ActionEvent arg0) {
         	             if (path != null){
         	            	 String fileToDelete = tree.getSelectionPath().getLastPathComponent().toString();
         	            	 System.out.println("Fichier a supprimer " + fileToDelete);
         	            	 //TODO Appeller Delete ici avec "fileToDelete" en parametre
         	            	getConnectionBeanThread().getFile().delete(fileToDelete);
         	             }
         	             
        			}
        		});
                 menu.show ( tree, pathBounds.x+30, pathBounds.y + pathBounds.height );
                 
             }
         } 		    
	}





	public void setClientBeanThread(String pathHome) {
		// TODO Auto-generated method stub
		if(this.port != 0 && !this.ip.equals("")){
			System.out.println("Path local : " + pathHome);
			pathHome = pathHome.replace("\\", "\\\\");
			pathHome+="\\\\";
			System.out.println("Path local : " + pathHome);
			s = new ServerAddress(ip, port);

			EjsGui.client = setConnectionBean(s, pathHome);

			System.out.println("Client started : id " + client.getId() + " name " + client.getName());
		}
		else{
			System.out.println("Connectez vous avant de choisir votre home directory !");
		}

	}
	
	public ClientBeanThread setConnectionBean(ServerAddress s2, String pathHome2){
		if(!clientBeanThreadIsCreate){
			ClientBeanThread clientBean;
			clientBean = new ClientBeanThread(s2, pathHome2);
			clientBean.start();
			clientBeanThreadIsCreate = true;
			return clientBean;
		}
		else{
			return EjsGui.client ;
		}
	}
	
	public static ClientBeanThread getConnectionBeanThread(){
			return EjsGui.client ;
		
	}
}
